<template>
  <div>
    <div
      v-if="filterable || checkAll"
      class="erp-form-checkbox-header"
    >
      <el-input
        v-if="filterable"
        v-model="keyword"
        class="keyword-input"
        suffix-icon="el-icon-search"
        :placeholder="filterablePlaceholder"
        clearable
      />
      <el-checkbox
        v-if="checkAll"
        v-model="checkedAll"
        :true-label="1"
        :false-label="0"
        @change="handleCheckedAll"
      >
        <span class="check-all">全选</span>
      </el-checkbox>
    </div>
    <el-checkbox-group
      v-model="valueModel"
      v-bind="props"
      @change="handleChange"
    >
      <el-checkbox
        v-for="(item,index) in computedOptions"
        :key="index"
        v-bind="item"
        :label="item[valueKey]"
        :disabled="item[disabledKey]"
        @change="handleChangeCheckbox($event, item[valueKey], index)"
      >
        {{ item[labelKey] }}
      </el-checkbox>
    </el-checkbox-group>
  </div>
</template>

<script>
import Vue from 'vue';
import {Checkbox, CheckboxGroup} from "element-ui";
import {cloneJson, inArray} from "@/utils";

Vue.use(Checkbox);
Vue.use(CheckboxGroup);
/**
 * 复选框组件
 * @author maolin
 */
export default {
  name: "ErpFormCheckbox",
  components: {
  },
  props: {
    /**
     * 标题
     * @public
     */
    title: {
      type: String,
      default: '',
    },
    /**
     * 字段
     * @public
     */
    field: {
      type: String,
      default: ''
    },
    /**
     * 值
     * @public
     */
    value: {
      default () {
        return [];
      }
    },
    /**
     * 复选框选项
     * @public
     */
    options: {
      type: Array,
      default () {
        return [];
      }
    },
    /**
     * element-ui中的[el-checkbox](https://element.eleme.cn/#/zh-CN/component/checkbox#checkbox-attributes)
     * @public
     */
    props: {
      type: Object,
      default () {
        return {};
      }
    },
    /**
     * 额外配置参数
     * ```js
     * return {
          valueKey: "value",
          labelKey: "label",
          disabledKey: "disabled",
          // 是否 传入以及返回都为数组格式，
          isArray: false,
          // 是否 可进行全选
          checkAll: false,
          // 是否 可进行搜索
          filterable: false,
          // 值类型，默认string，可选number
          valueType: "string",
        }
     * ```
     * @public
     */
    extra: {
      type: Object,
      default () {
        return {
          valueKey: "value",
          labelKey: "label",
          disabledKey: "disabled",
          // 是否 传入以及返回都为数组格式，
          isArray: false,
          // 是否 可进行全选
          checkAll: false,
          // 是否 可进行搜索
          filterable: false,
          // 值类型，默认string，可选number
          valueType: "string",
        };
      }
    }
  },
  data () {
    return {
      checkedAll: 0,
      keyword: null,
    };
  },
  computed: {
    computedOptions () {
      let keyword = this.keyword ? this.keyword.trim() : this.keyword;
      let op = this.options;
      let valueKey = this.valueKey;
      let options = op.map(item => {
        item[valueKey] = item[valueKey] !== undefined && item[valueKey] !== null ? (this.isNumber ? parseInt(item[valueKey]) : item[valueKey].toString()) : item[valueKey];
        return item;
      });
      let result = [];
      let labelKey = this.labelKey;
      if (!keyword) {
        result = options;
      } else if (options && options instanceof Array) {
        for (let i in options) {
          if (options[i][labelKey].includes(keyword)) {
            result.push(options[i]);
          }
        }
      }
      return result;
    },
    isNumber () {
      return this.extra && this.extra.valueType === 'number';
    },
    ableOptions () {
      let options = this.computedOptions;
      if (!(options instanceof Array)) {
        return [];
      }
      return options.filter((item) => {
        return !(this.disabledKey && item[this.disabledKey]);
      });
    },
    isArray () {
      return this.extra && this.extra.isArray === true;
    },
    checkAll () {
      return this.extra && this.extra.checkAll === true;
    },
    filterable () {
      return this.extra && this.extra.filterable === true;
    },
    filterablePlaceholder () {
      return this.extra && this.extra.filterablePlaceholder ? this.extra.filterablePlaceholder : '输入关键字搜索';
    },
    valueModel: {
      get () {
        return this.value ? (this.isArray ? this.value : this.value.split(',')) : [];
      },
      set (val) {
        val = val ? (this.isArray ? val : val.join(',')) : '';
        this.$emit('value-change', val);
      }
    },
    valueKey () {
      return this.extra && this.extra.valueKey ? this.extra.valueKey : 'value';
    },
    labelKey () {
      return this.extra && this.extra.labelKey ? this.extra.labelKey : 'label';
    },
    disabledKey () {
      return this.extra && this.extra.disabledKey ? this.extra.disabledKey : 'disabled';
    }
  },
  watch: {
    keyword (keyword) {

    }
  },
  mounted() {
  },
  methods: {
    /**
     * 选择了复选框
     * @private
     * @param {boolean} bool
     * @param {value} value 选择的值
     * @param {number} index 当前选择项的索引
     */
    handleChangeCheckbox (bool, value, index) {
      value = value === undefined || value === null ? '' : value;
      let valueToArray = this.value;
      if (!this.isArray) {
        valueToArray = valueToArray ? valueToArray.split(',') : [];
      }
      let valueArray = valueToArray.map(item => {
        item = item !== null ? (this.isNumber ? parseInt(item) : item.toString()) : item;
        return item;
      });
      let i = valueArray.indexOf(value.toString());
      if (i > -1) {
        // 存在,需要从数组中移除
        valueArray.splice(i,1);
      } else {
        // 不存在，往数组中加入
        valueArray.push(value);
      }
      this.valueModel = valueArray;
    },
    /**
     * 复选框组的选项发生变化
     * @private
     * @param e
     */
    handleChange (e) {
    },
    /**
     * 点击全选
     * @private
     * @param e
     */
    handleCheckedAll (e) {
      let data = [];
      let ableOptions = this.ableOptions;
      for (let i in ableOptions) {
        if (this.valueKey) {
          data.push(ableOptions[i][this.valueKey]);
        }
      }
      if (e) {
        this.valueModel = data;
      } else {
        this.valueModel = [];
      }
    }
  }
};
</script>

<style lang="scss" scoped>
    .erp-form-checkbox-header{
        margin-bottom: 10px;
        .keyword-input{
            max-width: 200px;
            margin-right: 10px;
        }
        .check-all{
            color: #999;
        }
    }


</style>
